#pragma once

#include <stdarg.h>
#include <time.h>
#include <unistd.h>

#include <iostream>

class LogLevel {
public:
    // 调试信息、一般信息、警告、错误、致命、未知
    enum Level { DEBUG = 0, INFO, WARN, ERROR, FATAL, UNKNOWN };

    static std::string toString(int level) {
        switch (level) {
            case 0:
                return "DEBUG";
            case 1:
                return "INFO";
            case 2:
                return "WARN";
            case 3:
                return "FATAL";
            case 4:
                return "UNKONWN";
            default:
                return "NOTSET";
        }
    }
};

class Logger {
private:
    char ret[25];
    const char* FormatTime();

public:
    Logger() : pid_(getpid()) {}

    void logMessage(LogLevel::Level level, const char* file, const char* function, int line, const char* format, ...);

    ~Logger() {}

private:
    uint32_t pid_;
};

extern Logger logger;

// 便捷日志宏
#define LOG_DEBUG(format, ...) \
    logger.logMessage(LogLevel::DEBUG, __FILE__, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)

#define LOG_INFO(format, ...) logger.logMessage(LogLevel::INFO, __FILE__, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)
#define LOG_WARN(format, ...) logger.logMessage(LogLevel::WARN, __FILE__, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)
#define LOG_ERROR(format, ...) \
    logger.logMessage(LogLevel::ERROR, __FILE__, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)

#define LOG_FATAL(format, ...) \
    logger.logMessage(LogLevel::FATAL, __FILE__, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)
